load("@bazel_skylib//lib:selects.bzl", "selects")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("//:build/kj_test.bzl", "kj_test")
load("//:build/wd_capnp_library.bzl", "wd_capnp_library")
load("//:build/wd_cc_binary.bzl", "wd_cc_binary")
load("//:build/wd_cc_embed.bzl", "wd_cc_embed")
load("//:build/wd_cc_library.bzl", "wd_cc_library")

config_setting(
    name = "is_linux",
    constraint_values = ["@platforms//os:linux"],
)

# Flag that can be used to force-disable tcmalloc. Mainly used for ASAN builds.
# TODO(cleanup): This feels ugly but I've exceeded my timebox for fighting Bazel for now.
bool_flag(
    name = "use_tcmalloc",
    build_setting_default = True,
)

config_setting(
    name = "set_use_tcmalloc",
    flag_values = {"use_tcmalloc": "True"},
)

selects.config_setting_group(
    name = "really_use_tcmalloc",
    match_all = [
        ":set_use_tcmalloc",
        ":is_linux",
    ],
)

# current malloc in use
wd_cc_library(
    name = "malloc",
    visibility = ["//visibility:public"],
    deps = select({
        ":really_use_tcmalloc": ["@tcmalloc//tcmalloc"],
        "//conditions:default": ["@bazel_tools//tools/cpp:malloc"],
    }),
)

wd_cc_embed(
    name = "workerd-capnp-schema",
    src = "workerd.capnp",
    base_name = "workerd-capnp-schema",
    is_text = True,
)

wd_cc_embed(
    name = "cpp-capnp-schema",
    src = "@capnp-cpp//src/capnp:c++.capnp",
    base_name = "cpp-capnp-schema",
    is_text = True,
)

wd_cc_binary(
    name = "workerd",
    srcs = ["workerd.c++"],
    malloc = ":malloc",
    visibility = ["//visibility:public"],
    deps = [
        ":cpp-capnp-schema",
        ":json-logger",
        ":server",
        ":v8-platform-impl",
        ":workerd-capnp-schema",
        ":workerd_capnp",
        "//src/pyodide:pyodide_extra_capnp",
        "//src/rust/cxx-integration",
        "//src/workerd/util:autogate",
        "//src/workerd/util:perfetto",
        "@capnp-cpp//src/capnp:capnpc",
    ],
)

wd_cc_library(
    name = "alarm-scheduler",
    srcs = [
        "alarm-scheduler.c++",
    ],
    hdrs = [
        "alarm-scheduler.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        "//src/workerd/io",
        "//src/workerd/util:sqlite",
        "@capnp-cpp//src/kj",
        "@capnp-cpp//src/kj:kj-async",
    ],
)

wd_cc_library(
    name = "actor-id-impl",
    srcs = [
        "actor-id-impl.c++",
    ],
    hdrs = [
        "actor-id-impl.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        "//src/workerd/io:actor-id",
        "//src/workerd/jsg:exception",
        "//src/workerd/util:entropy",
        "//src/workerd/util:own-util",
        "//src/workerd/util:thread-scopes",
        "@capnp-cpp//src/kj",
        "@ssl",
    ],
)

wd_cc_library(
    name = "pyodide",
    srcs = [
        "pyodide.c++",
    ],
    hdrs = [
        "pyodide.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        "//src/workerd/api:pyodide",
        "//src/workerd/io:compatibility-date_capnp",
        "//src/workerd/jsg",
        "@capnp-cpp//src/kj",
        "@capnp-cpp//src/kj:kj-async",
        "@capnp-cpp//src/kj/compat:kj-gzip",
        "@capnp-cpp//src/kj/compat:kj-tls",
    ],
)

wd_cc_library(
    name = "workerd-debug-port-client",
    srcs = [
        "workerd-debug-port-client.c++",
    ],
    hdrs = [
        "workerd-debug-port-client.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        "//src/workerd/io",
    ],
)

wd_cc_library(
    name = "workerd-api",
    srcs = [
        "workerd-api.c++",
    ],
    hdrs = [
        "workerd-api.h",
    ],
    implementation_deps = [
        "//src/workerd/api:analytics-engine",
        "//src/workerd/api:capnp",
        "//src/workerd/api:kv",
        "//src/workerd/api:streams",
        "//src/workerd/api:urlpattern",
        "//src/workerd/api:urlpattern-standard",
        "//src/workerd/api:worker-loader",
        "//src/workerd/io:promise-wrapper",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":actor-id-impl",
        ":fallback-service",
        ":pyodide",
        ":workerd-debug-port-client",
        ":workerd_capnp",
        "//src/cloudflare",
        "//src/node",
        "//src/pyodide:pyodide_static",
        "//src/pyodide:python-entrypoint",
        "//src/rust/transpiler",
        "//src/workerd/api:html-rewriter",
        "//src/workerd/api:hyperdrive",
        "//src/workerd/api:memory-cache",
        "//src/workerd/api:pyodide",
        "//src/workerd/api:r2",
        "//src/workerd/api:rtti",
        "//src/workerd/api/node",
        "//src/workerd/io",
        "//src/workerd/io:worker-modules",
        "//src/workerd/jsg",
        "//src/workerd/util:perfetto",
        "@capnp-cpp//src/kj/compat:kj-gzip",
        "@capnp-cpp//src/kj/compat:kj-tls",
    ],
)

wd_cc_library(
    name = "server",
    srcs = [
        "server.c++",
    ],
    hdrs = [
        "server.h",
    ],
    deps = [
        ":actor-id-impl",
        ":alarm-scheduler",
        ":container-client",
        ":facet-tree-index",
        ":fallback-service",
        ":workerd-api",
        ":workerd_capnp",
        "//src/cloudflare",
        "//src/node",
        "//src/pyodide:pyodide_static",
        "//src/workerd/api:memory-cache",
        "//src/workerd/api:pyodide",
        "//src/workerd/io",
        "//src/workerd/io:bundle-fs",
        "//src/workerd/io:trace-stream",
        "//src/workerd/io:worker-entrypoint",
        "//src/workerd/jsg",
        "//src/workerd/util:perfetto",
        "//src/workerd/util:websocket-error-handler",
        "@capnp-cpp//src/kj/compat:kj-gzip",
        "@capnp-cpp//src/kj/compat:kj-tls",
    ],
)

wd_capnp_library(src = "docker-api.capnp")

wd_capnp_library(src = "log-schema.capnp")

wd_cc_library(
    name = "json-logger",
    srcs = ["json-logger.c++"],
    hdrs = ["json-logger.h"],
    visibility = ["//visibility:public"],
    deps = [
        ":log-schema_capnp",
        "@capnp-cpp//src/capnp/compat:json",
        "@capnp-cpp//src/kj",
    ],
)

wd_cc_library(
    name = "container-client",
    srcs = ["container-client.c++"],
    hdrs = ["container-client.h"],
    visibility = ["//visibility:public"],
    deps = [
        ":docker-api_capnp",
        "//src/workerd/io:container_capnp",
        "//src/workerd/jsg",
        "@capnp-cpp//src/capnp/compat:http-over-capnp",
        "@capnp-cpp//src/kj",
        "@capnp-cpp//src/kj:kj-async",
        "@capnp-cpp//src/kj/compat:kj-http",
    ],
)

wd_cc_library(
    name = "fallback-service",
    srcs = [
        "fallback-service.c++",
    ],
    hdrs = [
        "fallback-service.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":workerd_capnp",
        "@capnp-cpp//src/kj",
        "@capnp-cpp//src/kj:kj-async",
        "@capnp-cpp//src/kj/compat:kj-http",
    ],
)

wd_cc_library(
    name = "v8-platform-impl",
    srcs = [
        "v8-platform-impl.c++",
    ],
    hdrs = [
        "v8-platform-impl.h",
    ],
    deps = [
        "//src/workerd/jsg",
        "@capnp-cpp//src/kj",
    ],
)

wd_cc_library(
    name = "facet-tree-index",
    srcs = [
        "facet-tree-index.c++",
    ],
    hdrs = [
        "facet-tree-index.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        "@capnp-cpp//src/kj",
    ],
)

wd_capnp_library(
    src = "workerd.capnp",
    # Limit visibility to avoid accidental usage – there should be no need to use this outside of
    # test-fixture and the workerd binary.
    visibility = [
        ":__pkg__",
        "//src/workerd/api:__pkg__",
        "//src/workerd/tests:__pkg__",
    ],
)

kj_test(
    size = "large",
    src = "server-test.c++",
    deps = [
        ":server",
        "//src/workerd/util:test-util",
    ],
)

kj_test(
    src = "actor-id-impl-test.c++",
    deps = [
        ":actor-id-impl",
        "//src/workerd/jsg:exception",
        "//src/workerd/util:thread-scopes",
        "@capnp-cpp//src/kj",
        "@ssl",
    ],
)

copy_file(
    name = "pyodide.capnp.bin@rule",
    src = "//src/pyodide:pyodide.capnp.bin_cross",
    out = "pyodide.capnp.bin",
)

kj_test(
    src = "facet-tree-index-test.c++",
    deps = [
        ":facet-tree-index",
        "@capnp-cpp//src/kj",
    ],
)

kj_test(
    src = "json-logger-test.c++",
    deps = [
        ":json-logger",
        "@capnp-cpp//src/capnp/compat:json",
    ],
)
